﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.IO ;
using System.Threading;
using System.Reflection;

namespace DataBGMonitor
{
    [ToolboxItem(true)]
    public partial class ControlGroup : UserControl
    {
        /// <summary>
        /// 服务名称
        /// </summary>
        private string _ServiceName =string.Empty ;

        [Browsable(false )]
        public string ServiceName
        {
            get
            {
                return _ServiceName;
            }
        }

        /// <summary>
        /// 动态链接库名称
        /// </summary>
        private string _DllName = string.Empty;

        [Browsable(false)]
        public string DllName
        {
            get
            {
                return _DllName;
            }
        }

        /// <summary>
        /// 动态链接库路径
        /// </summary>
        private string _DllPath = string.Empty ;

        [Browsable(false )]
        public string DllPath
        {
            get
            {
                return _DllPath ;
            }
        }

        /// <summary>
        /// 动态链接库版本
        /// </summary>
        private string _DllVersion = string.Empty;

        [Browsable(false)]
        public string DllVersion
        {
            get
            {
                return _DllVersion;
            }
        }

        /// <summary>
        /// 运行时间间隔
        /// </summary>
        private int _RunInterval;

        [Browsable(false)]
        public int RunInterval
        {
            get
            {
                return _RunInterval;
            }
        }

        /// <summary>
        /// 是否正在运行
        /// </summary>
        private bool _Running;

        [Browsable(false)]
        public bool Running
        {
            get
            {
                return _Running;
            }
        }

        /// <summary>
        /// 按间隔时间执行操作的计时器
        /// </summary>
        //private System.Threading .Timer _timer;
        private System.Windows.Forms.Timer _timer;

        [Browsable(false)]
        //public System.Threading.Timer timer
        public System.Windows.Forms.Timer timer
        {
            get
            {
                return _timer;
            }
        }

        /// <summary>
        /// 运行次数
        /// </summary>
        private int _RunCount = 0;

        [Browsable(false)]
        public int RunCount
        {
            get
            {
                return _RunCount;
            }
        }

        public ControlGroup()
        {
            InitializeComponent();
            _timer = new System.Windows.Forms.Timer();
            _timer.Tick += new EventHandler(Timer_Tick);
        }

        /// <summary>
        /// 初始化界面
        /// </summary>
        /// <returns></returns>
        private bool iniInterFace()
        {
            try
            {
                if (_DllPath.Trim().Equals(string.Empty))
                {
                    //如果动态链接库为空，不显示服务名称，不显示链接库名称，不显示链接库版本，设置及开始按钮都为不可用
                    gb.Text = string.Empty;
                    lblDllName.Text = string.Empty;
                    lblDllVersion.Text = string.Empty;
                    lblRunCount.Text = string.Empty;
                    lblRunInterval.Text = string.Empty;
                    btnConfig.Enabled = false;
                    btnStart.Enabled = false;
                }
                else
                {
                    //如果动态链接库不为空，显示服务名称，显示连接库名称，显示链接库版本，设置及开始按钮都为可用
                    gb.Text = _ServiceName+"("+DllName +")";
                    lblDllName.Text = DllName ;
                    lblDllVersion.Text = DllVersion;
                    lblRunCount.Text = "0";
                    lblRunInterval.Text = RunInterval.ToString ()+"秒";
                    _timer.Interval = RunInterval * 1000;
                    btnConfig.Enabled = true ;
                    btnStart.Enabled = true ;
                }
                return true;
            }
            catch(Exception ex)
            {
                MessageBox.Show("初始化服务控件失败：" + ex.Message,"提示",MessageBoxButtons.OK,MessageBoxIcon.Error );
                return false;
            }
        }

        /// <summary>
        /// 加载动态链接库
        /// </summary>
        /// <param name="strFileName">动态链接库文件名</param>
        /// <returns>是否加载成功</returns>
        public bool LoadDll(string strFileName)
        {
            if (File.Exists(strFileName))
            {
                //如果链接库文件存在，加载文件信息，初始化界面
                try
                {
                    //获取服务名称
                    object objname = GetDllProperty(strFileName, "ServiceName");
                    if (objname == null)
                    {
                        throw new Exception("获取动态链接库信息错误：无服务名称信息！");
                    }
                    //获取链接库版本
                    object objversion = GetDllProperty(strFileName, "DLLVersion");
                    if (objversion == null)
                    {
                        throw new Exception("获取动态链接库信息错误：无版本信息！");
                    }
                    //获取运行间隔
                    object objRunInterval= GetDllProperty(strFileName, "RunInterval");
                    if (objRunInterval == null)
                    {
                        throw new Exception("获取动态链接库信息错误：无运行间隔信息！");
                    }
                    _ServiceName = objname.ToString();
                    _DllVersion = objversion.ToString();
                    _RunInterval = Convert.ToInt32(objRunInterval);
                    _DllName = new FileInfo(strFileName).Name;
                    _DllPath = strFileName;
                    _Running = false;
                    iniInterFace();
                    return true;
                }
                catch(Exception ex)
                {
                    MessageBox.Show(ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return false;
                }
            }
            else
            {
                //如果链接库文件不存在，直接返回加载失败
                MessageBox.Show("动态链接库不存在！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
        }

        private object GetDllProperty(string strFileName,string strPropertyName)
        {
            Assembly ass;
            Type type;
            object obj;
            object objValue;
            try
            {
                 ass= Assembly.LoadFile(strFileName);

                //加载程序集，命名空间必须为Plugin，类名必须为Config
                type = ass.GetType("Plugin.Config");

                PropertyInfo proinfo = type.GetProperty(strPropertyName);

                obj = Activator.CreateInstance(type);
                
                objValue = proinfo.GetValue(obj ,null);

                return objValue;
            }
            catch(Exception ex)
            {
                MessageBox.Show("加载动态链接库"+DllName +"失败：" + ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return null;
            }
            finally
            {
                ass = null;
            }
        }

        /// <summary>
        /// 调用动态链接库中的方法
        /// </summary>
        /// <param name="strMethodName">要调用的方法名</param>
        private void RunMethod(string strMethodName)
        {
            Assembly ass;
            Type type;
            object obj;
            object objValue = null;
            if (File.Exists(_DllPath))
            {
                ass = Assembly.LoadFile(_DllPath);

                type = ass.GetType("Plugin.Service");

                MethodInfo method1 = type.GetMethod(strMethodName );

                if (method1 == null)
                {
                    throw new Exception("该插件未包含此功能！");
                }

                BindingFlags flag = BindingFlags.Public | BindingFlags.Instance;

                //obj = ass.CreateInstance ("DllClass.ReportDataBuilder");
                obj = Activator.CreateInstance(type);

                objValue = method1.Invoke(obj, flag, Type.DefaultBinder, null, null);
            }
        }

        /// <summary>
        /// 显示插件自带的设置窗体
        /// </summary>
        private void ShowConfig()
        {
            Assembly ass;
            Type type;
            object obj;
            object objValue = null;
            if (File.Exists(_DllPath))
            {
                ass = Assembly.LoadFile(_DllPath);

                type = ass.GetType("Plugin.Config");

                MethodInfo method1 = type.GetMethod("ShowConfig");

                if (method1 == null)
                {
                    throw new Exception("该插件未包含此功能！");
                }

                BindingFlags flag = BindingFlags.Public | BindingFlags.Instance;

                //obj = ass.CreateInstance ("DllClass.ReportDataBuilder");
                obj = Activator.CreateInstance(type);

                objValue = method1.Invoke(obj, flag, Type.DefaultBinder, null, null);
            }
        }

        private void btnConfig_Click(object sender, EventArgs e)
        {
            ShowConfig();
        }

        private void Start(object tmpobj)
        {
            _RunCount++;
            SetRunCountText (RunCount.ToString());
            RunMethod("Start");
            _timer.Enabled = true;
        }

        delegate void SetRunCountTextCallBack(string strTmp);

        private void SetRunCountText(string strTmp)
        {
            if (this.lblRunCount.InvokeRequired)
            {
                SetRunCountTextCallBack srctcb = new SetRunCountTextCallBack(SetRunCountText);
                this.Invoke(srctcb, new object[] { strTmp });
            }
            else
            {
                lblRunCount.Text = strTmp;
            }
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            if (!_Running)
            {
                //_timer = new System.Threading.Timer(new TimerCallback(Start), null, 0, RunInterval * 1000);
                _timer.Enabled = true;
                btnStart.ForeColor = Color.Red;
                btnStart.Text = "停  止";
                _Running = true;
                btnConfig.Enabled = false;
            }
            else
            {
                if (_timer != null)
                {
                    _timer.Enabled = false;
                    _timer.Dispose();
                }
                btnStart.ForeColor = Color.Black;
                btnStart.Text = "开  始";
                _Running = false ;
                btnConfig.Enabled = true ;
            }
        }

        private void Timer_Tick(object sender,EventArgs e)
        {
            _timer.Enabled = false;
            Start(this);
        }
    }
}
